home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 February (DVD) / PCWorld_2008-02_DVD.iso / v cisle / PHP / PHP.exe / xampp-win32-1.6.5-installer.exe / php / PEAR / Net / Dict.php < prev    next >
Encoding:
PHP Script  |  2007-12-20  |  14.0 KB  |  563 lines

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  4.  
  5. /**
  6.  * Net_Dict
  7.  *
  8.  * PHP Versions 4 and 5
  9.  *
  10.  * LICENSE: This source file is subject to version 2.02 of the PHP license
  11.  * that is available through the world-wide-web at the following URI:
  12.  * http://www.php.net/license/2_02.txt.  If you did not receive a copy of
  13.  * the PHP License and are unable to obtain it through the web, please
  14.  * send a note to license@php.net so we can mail you a copy immediately.
  15.  *
  16.  * @category   Networking
  17.  * @package    Net_Dict
  18.  * @author     Chandrashekhar Bhosle <cnb@freedomink.org>
  19.  * @author     Ian Eure <ieure@php.net>
  20.  * @copyright  (c) 2002 Chandrashekhar Bhosle
  21.  * @copyright  (c) 2005, 2006 Ian Eure
  22.  * @license    http://www.php.net/license/2_02.txt  PHP License 2.02
  23.  * @version    CVS: $Revision: 1.10 $
  24.  * @link       http://pear.php.net/package/Net_Dict
  25.  */
  26.  
  27. require_once 'PEAR.php';
  28. require_once 'Net/Socket.php';
  29.  
  30.  
  31. define('NET_DICT_SERVER', 'dict.org');
  32. define('NET_DICT_PORT',   '2628');
  33.  
  34. /**
  35.  * The main Net_Dict class
  36.  *
  37.  * Net_Dict is a PHP interface for talking to dictd servers.
  38.  *
  39.  * @package   Net_Dict
  40.  * @category  Networking
  41.  * @link      http://pear.php.net/package/Net_Dict
  42.  * @version   Release: @package_version@
  43.  * @version   CVS:     $Revision: 1.10 $
  44.  * @author    Chandrashekhar Bhosle <cnb@freedomink.org>
  45.  * @license   http://www.php.net/license/2_02.txt PHP License v2.02
  46.  */
  47. class Net_Dict {
  48.     /**
  49.      * Default DICT server name
  50.      *
  51.      * @var string
  52.      */
  53.     var $server = NET_DICT_SERVER;
  54.  
  55.     /**
  56.      * Default DICT Port
  57.      *
  58.      * @var int
  59.      */
  60.     var $port = NET_DICT_PORT;
  61.  
  62.     /**
  63.      * Socket object
  64.      *
  65.      * @var object
  66.      */
  67.     var $_socket;
  68.  
  69.     /**
  70.      * Server Information
  71.      *
  72.      * @var string
  73.      */
  74.     var $servinfo;
  75.  
  76.     /**
  77.      * if caching is on or off
  78.      *
  79.      * @var boolean
  80.      */
  81.     var $caching = false;
  82.  
  83.     /**
  84.      * PEAR Cache
  85.      *
  86.      * @var object
  87.      */
  88.     var $cache;
  89.  
  90.  
  91.     /**
  92.      * Gets definitions for the specified word in the specified database.
  93.      *
  94.      * @param   string  $word
  95.      * @param   string  $database
  96.      *
  97.      * @return  mixed   Array of definitions if sucessful, else PEAR_Error
  98.      */
  99.     function define($word, $database = '*')
  100.     {
  101.         if ($this->caching) {
  102.             if ($defines = $this->cache->get($word, 'Net_Dict_Defs')) {
  103.                 return $defines;
  104.             }
  105.         }
  106.  
  107.         if (!is_object($this->_socket)) {
  108.             $res = $this->connect();
  109.             if (PEAR::isError($res)) {
  110.                 return $res;
  111.             }
  112.         }
  113.  
  114.         $resp = $this->_sendCmd("DEFINE $database '$word'");
  115.  
  116.         if (PEAR::isError($resp)) {
  117.             return $resp;
  118.         }
  119.  
  120.         list($num) = explode(' ', $resp['text'], 2);
  121.  
  122.         for ($i = 0; $i < $num; $i++) {
  123.             $resp = $this->_socket->readLine();
  124.  
  125.             preg_match("/(\d{3})\s+?\"(.+)?\"\s+?(\S+)\s+?\"(.+)?\"/",
  126.                                                     $resp, $matches);
  127.  
  128.             $defines[$i]['response']    = $resp;
  129.             $defines[$i]['word']        = $matches[2];
  130.             $defines[$i]['database']    = $matches[3];
  131.             $defines[$i]['description'] = $matches[4];
  132.  
  133.             $resp = $this->_getMultiline();
  134.  
  135.             $defines[$i]['definition'] = $resp['text'];
  136.         }
  137.  
  138.         $this->readLine(); /* discard status */
  139.  
  140.         if ($this->caching) {
  141.             $this->cache->save($word, $defines, 0, 'Net_Dict_Defs');
  142.         }
  143.  
  144.         return $defines;
  145.     }
  146.  
  147.     /**
  148.      * Searches an index for the dictionary, and reports words
  149.      * which were found using a particular strategy.
  150.      *
  151.      * @param   string  $word
  152.      * @param   string  $strategy
  153.      * @param   string  $database
  154.      *
  155.      * @return  mixed   Array of matches if successful, else PEAR_Error
  156.      */
  157.     function match($word, $strategy = 'substring', $database = '*')
  158.     {
  159.         $resp = $this->_sendCmd("MATCH $database $strategy '$word'");
  160.  
  161.         if (PEAR::isError($resp)) {
  162.             return $resp;
  163.         }
  164.  
  165.         $resp = $this->_getMultiLine();
  166.  
  167.         $this->readLine(); /* discard status */
  168.  
  169.         preg_match_all("/(\S+)?\s\"(.+?)\"/", $resp['text'], $matches);
  170.  
  171.         for ($i = 0; $i < count($matches[0]); $i++) {
  172.             $matched[$i]['database'] = $matches[1][$i];
  173.             $matched[$i]['word']     = $matches[2][$i];
  174.         }
  175.  
  176.         return $matched;
  177.     }
  178.  
  179.     /**
  180.      * Gets list of available databases
  181.      *
  182.      * @return  mixed  Array of databases if successful, else PEAR_Error
  183.      */
  184.     function showDatabases()
  185.     {
  186.         $resp = $this->_sendCmd('SHOW DB');
  187.  
  188.         if (PEAR::isError($resp)) {
  189.             return $resp;
  190.         }
  191.  
  192.         $resp = $this->_getMultiLine();
  193.  
  194.         $this->readLine(); /* discard status */
  195.  
  196.         preg_match_all("/(\S+)?\s+?\"(.+?)\"/", $resp['text'], $matches);
  197.  
  198.         for ($i = 0; $i < count($matches[0]); $i++) {
  199.             $databases[$i]['database']    = $matches[1][$i];
  200.             $databases[$i]['description'] = $matches[2][$i];
  201.         }
  202.  
  203.         return $databases;
  204.     }
  205.  
  206.     /**
  207.      * Gets a list of available strategies
  208.      *
  209.      * @return mixed Array of strategies if successful, else PEAR_Error
  210.      */
  211.     function showStrategies()
  212.     {
  213.         $resp = $this->_sendCmd('SHOW STRAT');
  214.  
  215.         if (PEAR::isError($resp)) {
  216.             return $resp;
  217.         }
  218.  
  219.         $resp = $this->_getMultiLine();
  220.  
  221.         $this->readLine(); /* discard status */
  222.  
  223.         preg_match_all("/(\S+)?\s+?\"(.+?)\"/", $resp['text'], $matches);
  224.  
  225.         for ($i = 0; $i < count($matches[0]); $i++) {
  226.             $strategies[$i]['strategy']    = $matches[1][$i];
  227.             $strategies[$i]['description'] = $matches[2][$i];
  228.         }
  229.  
  230.         return $strategies;
  231.     }
  232.  
  233.     /**
  234.      * Gets source, copyright, and licensing information about the
  235.      * specified database.
  236.      *
  237.      * @param   string  $database
  238.      *
  239.      * @return  mixed   string if successful, else PEAR_Error
  240.      */
  241.     function showInfo($database)
  242.     {
  243.         return $this->simpleQuery('SHOW INFO ' . $database);
  244.     }
  245.  
  246.     /**
  247.      * Gets local server information written by the local administrator.
  248.      * This could include information about local databases or strategies,
  249.      * or administrative information such as who to contact for access to
  250.      * databases requiring authentication.
  251.      *
  252.      * @return  mixed  string if sucessful, else PEAR_Error
  253.      */
  254.     function showServer()
  255.     {
  256.         return $this->simpleQuery('SHOW SERVER');
  257.     }
  258.  
  259.     /**
  260.      * Allows the client to provide information about itself
  261.      * for possible logging and statistical purposes.  All clients SHOULD
  262.      * send this command after connecting to the server.  All DICT servers
  263.      * MUST implement this command (note, though, that the server doesn't
  264.      * have to do anything with the information provided by the client).
  265.      *
  266.      * @param   string  $text
  267.      *
  268.      * @return  mixed   string if successful, else PEAR_Error
  269.      */
  270.     function client($text = 'cnb')
  271.     {
  272.         $this->_sendCmd('CLIENT ' . $text);
  273.     }
  274.  
  275.     /**
  276.      * Display some server-specific timing or debugging information.  This
  277.      * information may be useful in debugging or tuning a DICT server.  All
  278.      * DICT servers MUST implement this command (note, though, that the text
  279.      * part of the response is not specified and may be omitted).
  280.      *
  281.      * @return  mixed  string if successful, else PEAR_Error
  282.      */
  283.     function status()
  284.     {
  285.         $resp = $this->_sendCmd('STATUS');
  286.         return $resp['text'];
  287.     }
  288.  
  289.     /**
  290.      * Provides a short summary of commands that are understood by this
  291.      * implementation of the DICT server.  The help text will be presented
  292.      * as a textual response, terminated by a single period on a line by
  293.      * itself.  All DICT servers MUST implement this command.
  294.      *
  295.      * @return  mixed  string on success, else PEAR_Error
  296.      */
  297.     function help()
  298.     {
  299.         return $this->simpleQuery('HELP');
  300.     }
  301.  
  302.     /**
  303.      * This command is used by the client to cleanly exit the server.
  304.      * All DICT servers MUST implement this command.
  305.      *
  306.      * @return  mixed  string on success, else PEAR_Error
  307.      */
  308.     function quit()
  309.     {
  310.         return $this->_sendCmd('QUIT');
  311.     }
  312.  
  313.     /**
  314.      * Requests that all text responses be prefaced by a MIME header
  315.      * [RFC2045] followed by a single blank line (CRLF).
  316.      *
  317.      * @return  mixed
  318.      * @todo    Implement this method
  319.      */
  320.     function optionMIME()
  321.     {
  322.     }
  323.  
  324.     /**
  325.      * The client can authenticate itself to the server using a username and
  326.      * password.  The authentication-string will be computed as in the APOP
  327.      * protocol discussed in [RFC1939].
  328.      *
  329.      * @param   string  $user
  330.      * @param   string  $auth
  331.      *
  332.      * @return  mixed
  333.      * @todo    Implement this method.
  334.      */
  335.     function auth($user, $auth)
  336.     {
  337.     }
  338.  
  339.     /**
  340.      * The Simple Authentication and Security Layer (SASL) is currently
  341.      * being developed [RFC2222].  The DICT protocol reserves the SASLAUTH
  342.      * and SASLRESP commands for this method of authentication.
  343.      *
  344.      * @param   string  $mechanism
  345.      * @param   string  $initial_response
  346.      * @return  mixed
  347.      * @todo    Implement this method.
  348.      */
  349.     function SASLAuth($mechanism, $initial_response)
  350.     {
  351.     }
  352.  
  353.     /**
  354.      * The client will send all responses using the SASLRESP command and a
  355.      * BASE64-encoded parameter.
  356.      *
  357.      * @param   string  $response
  358.      * @return  mixed
  359.      * @todo    Implement this method.
  360.      */
  361.     function SASLResp($response)
  362.     {
  363.     }
  364.  
  365.     /**
  366.      * Connects to a dict server and sets up a socket
  367.      *
  368.      * @param   string   $server
  369.      * @param   integer  $port
  370.      * @return  mixed    true on success, else PEAR_Error
  371.      */
  372.     function connect($server = '', $port = 0)
  373.     {
  374.         $s = new Net_Socket;
  375.  
  376.         if (empty($server)) {
  377.             $server = $this->server;
  378.         }
  379.  
  380.         if (0 == $port) {
  381.             $port = $this->port;
  382.         }
  383.  
  384.         $err = $s->connect($server, $port);
  385.  
  386.         if (PEAR::isError($err)) {
  387.             
  388.             return $err;
  389.         }
  390.  
  391.         $banner = $s->readLine();
  392.         $resp['code'] = substr($banner, 0, 3);
  393.         $resp['text'] = ltrim(substr($banner, 3));
  394.  
  395.         if (!Net_Dict::isOK($resp)) {
  396.             return new PEAR_Error($resp['text'],
  397.                                   $resp['code']);
  398.         }
  399.  
  400.         $reg = array();
  401.         preg_match("/\d{3} (.*) <(.*)> <(.*)>/", $banner, $reg);
  402.         $this->servinfo["signature"]    = $reg[1];
  403.         $this->servinfo["capabilities"] = explode(".", $reg[2]);
  404.         $this->servinfo["msg-id"]       = $reg[3];
  405.  
  406.         $this->_socket =& $s;
  407.  
  408.         return true;
  409.     }
  410.  
  411.     /**
  412.      * Disconnect from the dict server
  413.      *
  414.      * @see     Net_Socket::disconnect()
  415.      * @return  mixed  Net_Socket::disconnect()'s return value
  416.      * @author  Ian Eure <ieure@php.net>
  417.      */
  418.     function disconnect()
  419.     {
  420.         if (isset($this->_socket)) {
  421.             return $this->_socket->disconnect();
  422.         }
  423.         return new PEAR_Error('not connected');
  424.     }
  425.  
  426.     /**
  427.      * Sets the server and port of dict server
  428.      *
  429.      * @param   string  $server
  430.      * @param   int     $port
  431.      * @return  void
  432.      */
  433.     function setServer($server, $port = 0)
  434.     {
  435.         $this->server = $server;
  436.  
  437.         if (0 < $port) {
  438.             $this->port = $port;
  439.         }
  440.     }
  441.  
  442.     /**
  443.      * Sets caching on or off and provides the cache type and parameters
  444.      *
  445.      * @param   boolean  $cache
  446.      * @param   string   $container
  447.      * @param   array    $container_options
  448.      * @return  void
  449.      */
  450.     function setCache($flag = false, $container = '', $container_options = '')
  451.     {
  452.         $this->caching = $flag;
  453.  
  454.         if ($this->caching) {
  455.             require_once 'Cache.php';
  456.  
  457.             if (is_object($this->cache)) {
  458.                 unset($this->cache);
  459.             }
  460.  
  461.             $this->cache = new Cache($container, $container_options);
  462.         }
  463.     }
  464.  
  465.     /**
  466.      * Sends a command, checks the reponse, and
  467.      * if good returns the reponse, other wise
  468.      * returns false.
  469.      *
  470.      * @param   $cmd   Command to send (\r\n will be appended)
  471.      * @return  mixed  First line of response if successful, otherwise false
  472.      */
  473.     function _sendCmd($cmd)
  474.     {
  475.         $result = $this->_socket->writeLine($cmd);
  476.  
  477.         if (PEAR::isError($result) && $result) {
  478.             return $result;
  479.         }
  480.  
  481.         $data = $this->_socket->readLine();
  482.  
  483.         if (PEAR::isError($data)) {
  484.             return $data;
  485.         }
  486.  
  487.         $resp['code'] = substr($data, 0, 3);
  488.         $resp['text'] = ltrim(substr($data, 3));
  489.  
  490.         if (!Net_Dict::isOK($resp)) {
  491.             return new PEAR_Error($resp['text'],
  492.                                   $resp['code']);
  493.         }
  494.  
  495.         return $resp;
  496.     }
  497.  
  498.     /**
  499.      * Reads a multiline reponse and returns the data
  500.      *
  501.      * @return mixed string on success or PEAR_Error
  502.      */
  503.     function _getMultiline()
  504.     {
  505.         $data = '';
  506.         while (($tmp = $this->readLine()) != '.') {
  507.             if (substr($tmp, 0, 2) == '..') {
  508.                 $tmp = substr($tmp, 1);
  509.             }
  510.             $data .= $tmp . "\r\n";
  511.         }
  512.  
  513.         $resp['text'] = substr($data, 0, -2);
  514.  
  515.         return $resp;
  516.     }
  517.  
  518.     /**
  519.      * Alias to Net_Socket::readLine();
  520.      *
  521.      * @see Net_Socket::readLine();
  522.      */
  523.     function readLine()
  524.     {
  525.         return $this->_socket->readLine();
  526.     }
  527.  
  528.     /**
  529.      * Runs a generic dict query
  530.      *
  531.      * @param   string  $query
  532.      * @return  mixed   string on success, else PEAR_Error
  533.      */
  534.     function simpleQuery($query)
  535.     {
  536.         $resp = $this->_sendCmd($query);
  537.  
  538.         if (PEAR::isError($resp)) {
  539.             return $resp;
  540.         }
  541.  
  542.         $resp = $this->_getMultiLine();
  543.  
  544.         $this->readLine(); /* discard status */
  545.  
  546.         return $resp['text'];
  547.     }
  548.  
  549.     /**
  550.      * Checks if a response code is positive
  551.      *
  552.      * @param   array    $resp
  553.      * @return  boolean
  554.      */
  555.     function isOK($resp)
  556.     {
  557.         $positives = array(1, 2, 3);
  558.  
  559.         return in_array(substr($resp['code'], 0, 1), $positives);
  560.     }
  561. }
  562.  
  563. ?>